package br.perfiman.utils;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import br.perfiman.Constants.BovespaTaxes;
import br.perfiman.Constants.IRS;
import br.perfiman.model.Asset;
import br.perfiman.model.Portfolio;
import br.perfiman.model.Trade;

public class BussinessUtils {
	public static Double getFee(Trade trade){
		Double fee = 0d;
		if(trade.isDayTradeOperation()){
			fee = (trade.getAsset().getType().equals(Asset.TYPE_OPTIONS))? BovespaTaxes.OPTIONS_DAYTRADE: BovespaTaxes.DAYTRADE;
		} else {
			fee = (trade.getAsset().getType().equals(Asset.TYPE_OPTIONS))? BovespaTaxes.OPTIONS: BovespaTaxes.COMMON_MARKET;
		}
		return trade.getQuantity() * trade.getPrice() * fee; 
	}
	
	public static Double getIRS(Trade trade){
		//just applied for sell operations
		if(!trade.getType().equals(Trade.TYPE_SELL))
			return 0d;
		//just applied at positive trades in daytrade
		if((trade.getProfit() < 0) && trade.isDayTradeOperation())
			return 0d;
		return (trade.isDayTradeOperation())? 
				//in daytrade the IRS is applied to the trade's profit
				trade.getProfit() * IRS.IRS_DAYTRADE_PRE:
				//in common market the IRS is applied to total value	
				trade.getQuantity() * trade.getPrice() * IRS.IRS_COMMON_MARKET_PRE;			
	}

	public static Double getFinalPrice(Trade trade) {
		return (trade.getQuantity() * trade.getPrice()) + trade.getBrokerage() +
					trade.getFees();
	}
	
	public static Double getAveragePrice(Trade trade) {
		return getFinalPrice(trade) / trade.getQuantity();
	}
	
	public static Double getAverageSellPrice(Trade trade) {
		return ((trade.getQuantity() * trade.getPrice()) - trade.getBrokerage() -
					trade.getFees()) / trade.getQuantity();
	}

	public static Double getProfit(Trade trade) {
		return (getAverageSellPrice(trade) - trade.getBuyAveragePrice()) * trade.getQuantity();
	}
	
	public static Double getAveragePrice(List<Trade> trades){
		Double totalValue = 0d;
		Integer totalQty = 0;
		for(Trade trade: trades){
			totalQty += trade.getQuantity();
			totalValue += trade.getQuantity() * getAveragePrice(trade);
		}
		return totalValue / totalQty;
	}
	
	public static Double getPortfolioPrice(Portfolio portfolio, Trade trade){
		Double oldPrice = portfolio.getAveragePrice() * portfolio.getQuantity();
		Double newPrice = getAveragePrice(trade) * trade.getQuantity();
		return (oldPrice + newPrice) / (portfolio.getQuantity() + trade.getQuantity());
	}
	
	public static Date[] getMonthRange(Integer month, Integer year){
		Date[] dates = new Date[2];
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.MONTH, month - 1);
		calendar.set(Calendar.YEAR, year);
		dates[0] = calendar.getTime();
		
		calendar = new GregorianCalendar();
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.MONTH, month);
		calendar.set(Calendar.YEAR, year);
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		dates[1] = calendar.getTime();
		return dates;
	}
}
